	package lifeOfAFish.scenegraph.geom;

import java.io.File;

import javax.media.opengl.*;

import com.sun.opengl.cg.CgGL;
import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureIO;

import lifeOfAFish.scenegraph.*;
import lifeOfAFish.util.MeshLoader;
import com.sun.opengl.cg.CGcontext;
import com.sun.opengl.cg.CGparameter;
import com.sun.opengl.cg.CGprogram;
import com.sun.opengl.cg.CgGL;

public class sgGeomWaterSurface extends sgGeometry {

	private float m_alpha = 1.0f;
	private float[] m_points = new float[4];
	private sgVec3 m_normal = null;
	private boolean m_created = false;
	private int m_displayList = -1;
	private float m_res = 20.0f;
	private CGparameter m_cgMod = null;
	private CGparameter m_cgModelView = null;
	private CGprogram m_cgVertexProg = null;
	private int m_cgVertexProfile;
	private float m_waveMod = 0.0f;

	public sgGeomWaterSurface()
	{
	}
	
	public sgGeomWaterSurface(float[] p)
	{
		setPoints(p);
	}
	
	public sgGeomWaterSurface(float x1, float x2, float z1, float z2)
	{
		setPoints(x1, x2, z1, z2);
	}
	
	public void setRes(float r) {m_res = r;}
	
	// set the CG mod parameters
	public void setCGMod(CGparameter param){
		m_cgMod = param;
	}
	
	// set the CG model view matrix parameter
	public void setCGModelView(CGparameter param){
		m_cgModelView = param;
	}
	
	public void setCGVertexProfile(int param){
		m_cgVertexProfile = param;
	}
	
	public void setCGVertexProg(CGprogram param){
		m_cgVertexProg = param;
	}
	
	public void setAlpha(float a)
	{
		m_alpha = a;
	}
	
	public void setNormal(sgVec3 n){
		m_normal = n;
	}
	
	public void setPoints(float[] p){
		for (int i = 0; i < p.length; i++)
		{
			m_points[i] = p[i];
		}
	}
	
	public void setPoints(float x1, float x2, float z1, float z2)
	{
		float[] p = {x1, x2, z1, z2};
		this.setPoints(p);
	}
	
	// additional push - texture bit
	protected void push()
	{
		super.push();
		sgGlobals.gl.glPushAttrib(GL.GL_TEXTURE_BIT);
	}
	
	// additional pop
	protected void pop()
	{
		super.pop();
		sgGlobals.gl.glPopAttrib();
	}
	
	/**
	 * Render the model, optional binding texture if necessary
	 */
	protected void draw()
	{
		GL gl = sgGlobals.gl;
		
//		// set the current model view matrix in CG
//		CgGL.cgGLSetStateMatrixParameter(m_cgModelView,
//				CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX, CgGL.CG_GL_MATRIX_IDENTITY);
//		
//		CgGL.cgGLEnableProfile(m_cgVertexProfile);
//		CgGL.cgGLBindProgram(m_cgVertexProg);
		
		this.bindTexture();
		
		gl.glBegin(GL.GL_QUADS);
		float x = m_points[0];
		float width = m_points[1]-m_points[0];
		float sx = width/m_res;
		for(;x < m_points[0]+width; x += sx){
			float y = m_points[2];
			float height = m_points[3]-m_points[2];
			float sy = height/m_res; 
			for(;y < m_points[2]+height; y += sy){
				float h = (float)Math.random();
				
//				CgGL.cgGLSetParameter3f(m_cgMod, m_waveMod, 1.0f, 1.0f);
				
				gl.glTexCoord2f(x/width, y/height); gl.glVertex3f(x, getH(x,y), y);
				gl.glTexCoord2f((x+sx)/width, y/height); gl.glVertex3f(x+sx, getH(x+sx,y), y);
				gl.glTexCoord2f((x+sx)/width, (y+sy)/height); gl.glVertex3f(x+sx, getH(x+sx,y+sy), y+sy);
				gl.glTexCoord2f((x)/width, (y+sy)/height); gl.glVertex3f(x, getH(x,y+sy), y+sy);
				
				m_waveMod += 0.00005f;
				if (m_waveMod > 2*Math.PI)									// Prevent Crashing
					m_waveMod = 0.0f;
			}
			
		}
		gl.glEnd();
		
		this.unbindTexture();
		
//		CgGL.cgGLDisableProfile(m_cgVertexProfile);
		
		
	};
	
	private float getH(float x, float z){
		return ((float)Math.sin(m_waveMod + (6.0*x) ) + (float)Math.sin(m_waveMod + (5.0*z) ) ) * 0.02f;
	}
	/**
	 * Return (local) bounding box
	 */
	public float[] getBoundingBox(){
		
		float[] ret = {m_points[0], m_points[1], 0.0f, 0.0f, m_points[2], m_points[3]};
		return ret;
		
	}

}
